#https://www.cnblogs.com/lc1217/p/6514734.html
##最小二乘法
import numpy as np   ##科学计算库 
import scipy as sp   ##在numpy基础上实现的部分算法库
from scipy.optimize import leastsq  ##引入最小二乘法算法
import datetime
from stockSelect10_soup_phone import getstock

'''
    设定拟合函数和偏差函数
    函数的形状确定过程：
    1.先画样本图像
    2.根据样本图像大致形状确定函数形式(直线、抛物线、正弦余弦等)
'''
##需要拟合的函数func :指定函数的形状y=kx+b
def func(p,x):
    m,k,b=p
    m=0 #此时为1次式
    return k*x+b+m*x*x

##偏差函数：x,y都是列表:这里的x,y更上面的Xo,Yh中是一一对应的
def error(p,x,y):
    return func(p,x)-y

##样本数据(Xo,Yh)，需要转换成数组(列表)形式
# Xo=np.array([6.19,2.51,7.29,7.01,5.7,2.66,3.98,2.5,9.1,4.2])
# Yh=np.array([5.25,2.83,6.41,6.71,5.1,4.23,5.05,1.98,10.5,6.3])
symbols=['2108','2600','2146','2938','2269'] #[沧州明珠,领益制造,荣盛发展,鹏鼎控股,美邦服饰]
for i in symbols:
    gs=getstock(i)
    df7=gs.dayN(7)
    # print(df7)
    # df7["wave"]=df7["high"].values-df7["low"].values
    # plt.plot(df7["wave"])
    # plt.show() 
    Yh=df7["high"].values
    Yl=df7["low"].values
    Xo=df7["open"].values
    # Xc=df7["close"].values
    # print("--------------------------")
    # print(Xo)
    # print(Xc)
    # print("--------------------------")
    # date= df7["date"]

    '''
        主要部分：附带部分说明
        1.leastsq函数的返回值tuple，第一个元素是求解结果，第二个是求解的代价值(个人理解)
        2.官网的原话（第二个值）：Value of the cost function at the solution
        3.实例：Para_high=>(array([ 0.61349535,  1.79409255]), 3)
        4.返回值元组中第一个值的数量跟需要求解的参数的数量一致
    '''

    #k,b的初始值，可以任意设定,经过几次试验，发现p0的值会影响cost的值：Para_high[1]
    p0=[0,1,2]

    #把error函数中除了p0以外的参数打包到args中(使用要求)
    Para_high=leastsq(error,p0,args=(Xo,Yh))
    Para_low=leastsq(error,p0,args=(Xo,Yl))
    #https://baike.baidu.com/item/黑塞矩阵/2248782?fr=aladdin
    #读取结果
    # m,k,b=Para_high[0]
    # ml,kl,bl=Para_low[0]
    # err=np.sum(error(Para_high[0],Xo,Yh)**2)/len(Xo)
    # print("平均误差",err)
    # print("预测目标数据:",func(Para_high[0],Xo))
    # print("真实目标数据:",Yh)
    # print("误差:",error(Para_high[0],Xo,Yh))
    # print("m=",m,"k=",k,"b=",b)
    # print("cost："+str(Para_high[1]))
    # print("求解的拟合直线为:")
    # print("y_high="+str(round(m,2))+"x*x+"+str(round(k,2))+"x+"+str(round(b,2)))
    # print("y_low="+str(round(ml,2))+"x*x+"+str(round(kl,2))+"x+"+str(round(bl,2)))
    xo1=float(gs.open)
    print(gs.name)
    print("预估最高价:",func(Para_high[0],xo1))
    print("预估最低价:",func(Para_low[0],xo1))
